package agh.tk.markuptranslation.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.antlr.runtime.RecognitionException;

import agh.tk.markuptranslation.DokuWikiParser;
import agh.tk.markuptranslation.HtmlAdapter;
import agh.tk.markuptranslation.IComponent;
import agh.tk.markuptranslation.MainDokuWiki;
import agh.tk.markuptranslation.MainMediaWiki;
import agh.tk.markuptranslation.MainTxt2Tags;
import agh.tk.markuptranslation.MediaWikiParser;
import agh.tk.markuptranslation.Txt2tagsParser;

public class Main {
	private static Logger logger = Logger.getLogger("markuptranslator");
	static JTextArea code;
	static JEditorPane htmlView;
	static File currentFile = null;
	static JFileChooser fc;
	enum Language {
		HTML("HTML"),
		MEDIAWIKI("MediaWiki"),
		TXT2TAGS("txt2tags"),
		DOKUWIKI("DokuWiki");
		private final String desc;
		Language(String desc) {
			this.desc = desc;
		}
		@Override
		public String toString() {
			return desc;
		}
	}
	static String[] sourceLanguages = {"", "txt2tags", "MediaWiki", "DokuWiki"};
	static Language[] destLanguages = {Language.TXT2TAGS, Language.DOKUWIKI, Language.MEDIAWIKI, Language.HTML};
	static Language dest = Language.TXT2TAGS;
	static String source;
	static JFrame frame;
	
	public static void setText(String s) {
		code.setText(s);
		updateView();
	}
	
	public static String getText() {
		return code.getText();
	}
	
	public static void setFile(File f) {
		currentFile = f;
	}
	
	public static File getFile() {
		return currentFile;
	}
	
	private static InputStream stringToInputStream(String string) {
		try {
			ByteArrayInputStream stream = new ByteArrayInputStream(string.getBytes("UTF-8"));
			return stream;
		} catch(UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	private static IComponent getSourceRoot() throws IOException, RecognitionException {
		InputStream stream = stringToInputStream(code.getText());
		IComponent component = null;
		if(source == null || source.equals("") || code.getText() == null) {
			return null;
		} else if (source.equals("txt2tags")) {
			Txt2tagsParser parser = MainTxt2Tags.createTxt2tagsParser(stream);
			component = parser.txt2tagsFile().value;
		} else if (source.equals("MediaWiki")) {
			MediaWikiParser parser = MainMediaWiki.createMediaWikiParser(stream);
			component = parser.start().value;
		} else if (source.equals("DokuWiki")) {
			DokuWikiParser parser = MainDokuWiki.createDokuWikiParser(stream);
			component = parser.start().value;
		} 
		return component;
	}
	
	private static void updateView() {
		try {
			IComponent component = getSourceRoot();
			if(component == null) {
				return;	
			}
			String html = component.toHTML();
			html = HtmlAdapter.convertToFullHTML(html);
			htmlView.setContentType("text/html");
			htmlView.setText(html);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void convert() {
		try {
			IComponent component = getSourceRoot();
			if(component == null) {
				return;	
			}
			switch(dest) {
				case DOKUWIKI:
					code.setText(component.toDokuWiki());
					break;
				case MEDIAWIKI:
					code.setText(component.toMediaWiki());
					break;
				case HTML:
					code.setText(component.toHTML());
					break;
				case TXT2TAGS:
					code.setText(component.toTxt2tags());
					break;
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	private static void createAndShowGUI() {
		//Try to set system L&F
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch(Exception e) {
			logger.warning("Could not set system look and feel: "+e.toString());
		}
		
		//Set up a frame
		frame = new JFrame("Markup languages translator");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setPreferredSize(new Dimension(600, 400));
		
		fc = new JFileChooser();
		
		//Set up the menu
		JMenuBar menu = new JMenuBar();
		JMenu fileMenu = new JMenu("File");
		JMenuItem newFile = new JMenuItem(new NewAction());
		Action open = new OpenAction(frame);
		JMenuItem openFile = new JMenuItem(open);
		//openFile.setAction(a);
		JMenuItem saveFile = new JMenuItem(new SaveAction());
		JMenuItem saveFileAs = new JMenuItem(new SaveAsAction());
		JMenuItem exit = new JMenuItem("Exit");
		exit.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		JFileChooser fileChooser = new JFileChooser();
		fileMenu.add(newFile);
		fileMenu.add(openFile);
		fileMenu.add(saveFile);
		fileMenu.add(saveFileAs);
		fileMenu.add(new JSeparator());
		fileMenu.add(exit);
		menu.add(fileMenu);
		frame.setJMenuBar(menu);
		
		//Set up tabs
		JTabbedPane tabs = new JTabbedPane();
		tabs.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				updateView();
			}
		});
		JPanel codeTab = new JPanel();
		codeTab.setLayout(new BorderLayout());
		code = new JTextArea();
		code.setFont(code.getFont().deriveFont(code.getFont().getSize2D()*1.5f));
		codeTab.add(new JScrollPane(code), BorderLayout.CENTER);
		JPanel htmlTab = new JPanel();
		htmlTab.setLayout(new BorderLayout());
		htmlView = new JEditorPane();
		htmlView.setEditable(false);
		htmlTab.add(new JScrollPane(htmlView));
		tabs.addTab("Code", codeTab);
		tabs.addTab("View", htmlTab);
		frame.add(tabs);
		
		//Bottom panel
		JPanel bottom = new JPanel();
		JLabel label1 = new JLabel("Source language ");
		JComboBox source = new JComboBox(sourceLanguages);
		source.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				JComboBox combo = (JComboBox)e.getSource();
				Main.source = (String)combo.getSelectedItem();
			}
		});
		JLabel label2 = new JLabel("Destination language ");
		JComboBox dest = new JComboBox(destLanguages);
		dest.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				JComboBox combo = (JComboBox)e.getSource();
				Main.dest = ((Language)combo.getSelectedItem());
			}
		});
		JButton convertButton = new JButton("Convert!");
		convertButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				convert();
			}
		});
		bottom.add(label1);
		bottom.add(source);
		bottom.add(label2);
		bottom.add(dest);
		bottom.add(convertButton);
		codeTab.add(bottom, BorderLayout.SOUTH);
		
		frame.pack();
		frame.setVisible(true);
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				createAndShowGUI();
			}
		});

	}

}
